# coding: utf-8

import time
import json
import requests
from requests.exceptions import HTTPError
from xls import xls_file_to_json
import toml

# 调用(云函数(实质就是api接口)
def callAliyunFunc(url, json_from_client):
    headers = {
        # "Host": "1825138619804807.cn-zhangjiakou.fc.aliyuncs.com",
        "Content-Type": "application/json",
        "Cache-Control": "no-cache",
    }
    # 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
    json_str = json.dumps(json_from_client, ensure_ascii=True)
    # print(json_str)
    # 发送post请求
    response = requests.post(url, data=json_str, headers=headers)
    print(url)
    # print(json_str)
    # If the response was successful, no Exception will be raised
    response.raise_for_status()
    return response


def read_json_file(json_file, encoding="utf-8"):
    root = None
    with open(json_file, "r", encoding=encoding) as f:
        root = json.load(f)
    return root


# 将 2020/10/9 15:50:42 格式字符串 转换成 unix timestamp
def makeTimestamp(str_time):
    try:
        return int(
            time.mktime(time.strptime(str_time.replace("/", "-"), "%Y-%m-%d %H:%M:%S"))
        )
    except:
        return int(time.time())


# 获取当前时间的unix timestamp
def currentTimestamp():
    return int(time.time())


# 下载指定时间5分钟内的传感器数据
def query_sensor_datas(url, timestamp, json_from_client):
    max_retries = 3
    results = None
    for _ in range(max_retries):
        try:
            # 开始计时
            start = time.process_time()
            print(
                "[%s]下载%s~%s传感器数据(状态类:%d个 数据类:%d个)"
                % (
                    time.strftime("%Y/%m/%d %H:%M:%S"),
                    time.strftime("%H:%M:%S", time.localtime(timestamp - 300)),
                    time.strftime("%H:%M:%S", time.localtime(timestamp)),
                    len(json_from_client["status"]),
                    len(json_from_client["value"]),
                )
            )
            # 传感器数据下载接口(阿里云)
            # url = "https://1825138619804807.cn-zhangjiakou.fc.aliyuncs.com/2016-08-15/proxy/jl/api/monitor/upload"
            # ?start=1605418480
            # url = "https://1825138619804807.cn-zhangjiakou.fc.aliyuncs.com/2016-08-15/proxy/jl/api/monitor/average"
            response = callAliyunFunc(
                "%s?start=%d" % (url, timestamp), json_from_client
            )
            # 结束计时
            end = time.process_time()
            print("状态码:%d 云函数耗时:%f s" % (response.status_code, end - start))
            # 提取返回结果
            results = json.loads(response.content)
            # print("查询结果:", results)
            break
        except HTTPError as http_err:
            # raise Exception(f"HTTP错误: {http_err}")
            print(f"[query_sensor_datas]HTTP错误: {http_err}")
            time.sleep(5)
            results = None
            continue
        except Exception as err:
            # raise Exception(f"其它错误: {err}")
            print(f"[query_sensor_datas]其它错误: {err}")
            time.sleep(5)
            results = None
            continue
    if results == None:
        raise Exception("[query_sensor_datas]超过重试次数(max_retries=%d)" % max_retries)
    return results


def main(timeout):
    # 读取传感器配置表格
    config = xls_file_to_json("./sensor_config.xls")
    # print(config)

    sensor_catalog_metic_dict = dict(
        [(catalog["name"], catalog["metric"]) for catalog in config["catalogs"]]
    )

    is_valid_sensor = (
        lambda sensor: sensor["catalog"] != None
        and sensor["catalog"].strip() != ""
        and sensor["used"] != None
        and int(sensor["used"]) == 1
    )

    # 正在使用的传感器
    # sensor_devices = [ { uuid, metric }, ... ]
    used_sensor_devices = [
        {
            "id": sensor["id"],
            "uuid": sensor["uuid"],
            "metric": sensor_catalog_metic_dict[sensor["catalog"]],
        }
        for sensor in config["devices"]
        if is_valid_sensor(sensor)
    ]

    # print(used_sensor_devices)

    api_config = toml.load("./api_config.toml")
    url = f"http://{api_config['sensor']['url']}/{api_config['sensor']['average_api']}"
    print("url:", url)

    while True:
        # 获取时间戳
        timestamp = currentTimestamp() - 60
        # 在云端下载数据
        result = query_sensor_datas(
            url,
            timestamp,
            {
                "status": [
                    sensor["uuid"]
                    for sensor in used_sensor_devices
                    if sensor["metric"] == "status"
                ],
                "value": [
                    sensor["uuid"]
                    for sensor in used_sensor_devices
                    if sensor["metric"] == "value"
                ],
            },
        )
        if result == None:
            raise Exception("query_sensor_datas()返回None, 原因未知")
        if result.get("status", 0) == 0:
            raise Exception("下载数据失败, status={0}".format(result.get("status", 0)))
        data = result.get("data", None)
        if data == None:
            raise Exception("下载数据失败, data=None")

        for x in data:
            print(x, end=",")
            print()
        print()
        print()
        time.sleep(timeout)


if __name__ == "__main__":
    try:
        timeout = 6
        main(timeout)
    except Exception as err:
        print(err)
